package com.iceberg;

import java.awt.*;
import java.util.Stack;

public class AlgorithmVisualizer {

    // TODO: 创建自己的数据
    private int DELAY = 80;
    private static int blockSize = 8;
    private static final int d[][] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    private MazeData data;        // 数据
    private AlgorithmFrame frame;    // 视图

    public AlgorithmVisualizer(String fileName){

        // 初始化数据
        // TODO: 初始化数据
        data = new MazeData(fileName);
        int sceneHeight = data.N() * blockSize;
        int sceneWidth = data.M() * blockSize;
        // 初始化视图
        EventQueue.invokeLater(() -> {
            frame = new AlgorithmFrame("Welcome", sceneWidth, sceneHeight);
            new Thread(() -> {
                run();
            }).start();
        });
    }

    // 动画逻辑
    private void run(){

        setData(-1, -1, true);

        Stack<Position> stack = new Stack<>();
        Position entrance = new Position(data.getEntranceX(), data.getEntranceY(), null);
        stack.push(entrance);
        data.visited[entrance.getX()][entrance.getY()] = true;
        boolean isSolved = false;
        while (!stack.isEmpty()){
            Position curPos = stack.pop();
            setData(curPos.getX(), curPos.getY(), true);

            if (curPos.getX() == data.getExitX() && curPos.getY() == data.getExitY()){
                isSolved = true;
                findPath(curPos);
                break;
            }
            for (int i = 0; i < 4; i ++){
                int newX = curPos.getX() + d[i][0];
                int newY = curPos.getY() + d[i][1];

                if (data.inArea(newX, newY) && !data.visited[newX][newY] && data.getData(newX, newY) == MazeData.ROAD){
                    stack.push(new Position(newX, newY, curPos));
                    data.visited[newX][newY] = true;
                }
            }
        }
        if (!isSolved){
            System.out.println("the maze has no solution");
        }
        setData(-1, -1, false);
    }

    private void findPath(Position des){
        Position cur = des;
        while (cur != null){
            data.result[cur.getX()][cur.getY()] = true;
            cur = cur.getPrev();
        }
    }

    private void setData(int x, int y, boolean isPath){
        if (data.inArea(x, y)){
            data.path[x][y] = isPath;
        }
        frame.render(data);
        AlgorithmVisHelper.pause(DELAY);
    }

    public static void main(String[] args) {
        AlgorithmVisualizer visualizer = new AlgorithmVisualizer("D:/VVader/GIT/DataStructureAlgorithms/Maze/src/com/iceberg/maze_101_101.txt");
    }
}
